from configparser import ConfigParser, NoOptionError
import logging
import datetime
from ding import data, notice
from collections import Counter
from Cryptodome.Cipher import Salsa20
import base64


def salsa_encrypt(text: str):
    """
    字符串加密
    :param text 需要加密的文本
    :return:
    """
    key = cf_connect('settings', 'key')
    if len(key) not in [16, 32]:
        logging.error("密钥长度错误，必须为16或32字节")
    enc = Salsa20.new(key.encode('utf-8'))
    res = enc.nonce + enc.encrypt(text.encode('utf-8'))
    res = base64.b64encode(res)
    return res


def salsa_decrypt(text: str):
    """
    字符串解密
    :param text: 需要解密的文本
    :return:
    """
    key = cf_connect('settings', 'key')
    if len(key) not in [16, 32]:
        logging.error("密钥长度错误，必须为16或32字节")
    data = base64.b64decode(text)
    nonce = data[:8]
    ciphertext = data[8:]
    enc = Salsa20.new(key.encode('utf-8'), nonce)
    res = enc.decrypt(ciphertext)
    return res


def cf_connect(section: str = '', key: str = ''):
    """
    返回配置文件内容
    :param section: 配置文件section
    :param key: 配置的key
    :return: 如果只提供了section参数，返回section下的所有配置项的名称；
             如果提供了section和key参数，返回该配置项的值；
             否则返回整个配置对象。
    """
    cf = ConfigParser()
    cf.optionxform = str
    cf.read('config.ini', encoding='utf-8')
    try:
        if key:
            return cf.get(section, key)
        elif section:
            return cf.options(section)
        else:
            return cf
    except NoOptionError as ex:
        logging.error(f"配置 key[{key}]不存在! {ex}")


def weekly_task():
    """
    返回上周告警情况
    :return:
    """
    if not data.db_status():
        return
    es = data.es_connect()
    index_name = cf_connect('es', 'index_name')
    today = datetime.date.today()
    last_week_start = today - datetime.timedelta(days=today.weekday() + 7)
    last_week_end = today - datetime.timedelta(days=today.weekday() + 1)
    query = {
        "query": {
            "range": {
                "TS": {
                    "gte": last_week_start,
                    "lte": last_week_end
                }
            }
        },
        "_source": ["alertname"],
        "size": 2000
    }
    # 查询上周的告警记录
    res = es.search(index=index_name, body=query)
    alert_list = []
    for hit in res['hits']['hits']:
        alert_list.append(hit['_source'])
    result = Counter([alert['alertname'] for alert in alert_list])
    keys_to_remove = list(result.keys())[5:]
    for key in keys_to_remove:
        result.pop(key)
    push_dest = cf_connect('settings', 'push_dest')
    group = cf_connect(push_dest, 'week_task')
    logging.info(result)
    notice.Notice(result, group).task_temp()
